2-5 扩展Rollup简介
Rollup 与 Vue 的渊源
从 Vue 1.0 开始,核心库的打包就由 Webpack 切换为 Rollup。Vue CLI(4.x 版本)仍然使用 Webpack 打包应用代码,但 Vue 核心库始终使用 Rollup 打包。选择 Rollup 的原因主要包括:
- Rollup 在库打包场景下性能表现优于 Webpack
- 原生支持 ES Module 规范,适合库文件的按需引入和导出
- Vue 2/3 出于历史原因保留了 Babel、ESLint、Webpack 等技术栈,但核心库的打包始终使用 Rollup
Rollup 的核心特点
Rollup 是一个 JavaScript 模块打包器,将小块代码编译成大块的复杂代码。与 Webpack 的关键区别在于:Rollup 使用 ES6 标准化的模块格式,而非 CommonJS 或 UMD。
ES Module 的优势
ES Module 是 JavaScript 的官方标准,也是语言明确的发展方向。相比 CommonJS:
- 静态分析:ES Module 支持静态分析,使得 Tree Shaking 成为可能——打包时自动移除未使用的代码
- 按需引入/导出:可以无缝使用库中的独立函数,不必引入整个库
- 面向未来:随着浏览器和 Node.js 原生支持 ES Module,CommonJS 将逐渐被替代
Tree Shaking 详解
Tree Shaking(摇树优化)与"按需加载"概念接近,核心作用是清除无用代码。它依赖 ES Module 的静态结构特性:
// math.js
export function add(a, b) { return a + b; }
export function multiply(a, b) { return a * b; }
// main.js
import { add } from './math.js'; // 只引入 add
// multiply 不会出现在最终打包产物中
javascript
核心概念
Rollup 的核心概念与 Webpack 类似:
| 概念 | 说明 |
|---|---|
| input | 入口文件 |
| output | 输出配置(file、format、name 等) |
| plugins | 扩展功能的插件 |
| external | 外部依赖,不打包进产物 |
安装与基础使用
安装
# 推荐在项目中安装
npm install -D rollup
# 不推荐全局安装
# npm install -g rollup
bash
注意:项目目录名不要叫
rollup,否则npm install rollup时会因包名冲突导致安装失败。使用rollup-demo等名称即可。
命令行打包
# 基础打包:指定入口、格式、输出文件
npx rollup src/main.js -f cjs -o dist/bundle.js
# 格式选项:amd / cjs / es / iife / umd / system
bash
配置文件方式
创建 rollup.config.js(支持 ES Module 语法):
// 单输出配置
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'cjs',
},
};
javascript
多输出配置
一次打包同时输出 CommonJS 和 ES Module 两种格式:
// 方式一:导出数组
export default [
{
input: 'src/main.js',
output: {
file: 'dist/bundle.cjs.js',
format: 'cjs',
},
},
{
input: 'src/main.js',
output: {
file: 'dist/bundle.es.js',
format: 'es',
},
},
];
// 方式二:output 为数组
export default {
input: 'src/main.js',
output: [
{ file: 'dist/bundle.cjs.js', format: 'cjs' },
{ file: 'dist/bundle.es.js', format: 'es' },
],
};
javascript
在 package.json 中配置构建命令:
{
"scripts": {
"build": "rollup -c"
}
}
json
插件系统
Rollup 通过插件扩展功能,常用插件可在 awesome-rollup 中找到。
示例:使用 terser 压缩代码
npm install -D @rollup/plugin-terser
bash
import terser from '@rollup/plugin-terser';
export default {
input: 'src/main.js',
output: [
{ file: 'dist/bundle.cjs.js', format: 'cjs' },
{ file: 'dist/bundle.es.js', format: 'es' },
],
plugins: [terser()],
};
javascript
添加 terser 后,打包产物会被压缩为单行代码。
插件执行顺序
Rollup 的插件是顺序引用、顺序执行。这与 Webpack 的 Loader(顺序引用、逆序执行)恰好相反。
Rollup vs Webpack
| 维度 | Rollup | Webpack |
|---|---|---|
| 定位 | 库/框架打包 | 应用打包 |
| 模块规范 | 原生 ES Module | CommonJS 为主,兼容 ES Module |
| Tree Shaking | 原生支持,效果更好 | 需要配置,效果略逊 |
| 配置复杂度 | 简洁 | 较复杂 |
| 插件生态 | 面向库开发 | 面向应用开发,更丰富 |
| 代码分割 | 支持但非强项 | 原生支持,功能完善 |
| 插件执行 | 顺序执行 | Loader 逆序执行 |
进阶学习
掌握了 Rollup 的基础后,可以阅读 Vue 核心库的 rollup.config.js 配置文件,理解一个真实的大型开源项目是如何使用 Rollup 的——包括多格式输出(CommonJS、ES Module、Runtime)、external 配置、以及各种插件的实际用法。
↑